/**
 * \file UnitTestHelper.h
 * \author T. M. Jandreau
 * \date December 22, 2012
 * 
 * This file contains static functions designed to take the stress off the
 * unit testing program. This includes an ability to ensure directories are present, 
 * how to count files, etc.
 */

#ifndef __UNIT_TEST_HELPER_H__
#define __UNIT_TEST_HELPER_H__

#include <sys/types.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>

#include <sys/stat.h>

namespace TEST { // using namespace TEST

    ///\brief Ensures a file is present in the filesystem
    /**
     * This function ensures that a file is present by running a UNIX stat call
     * @param filename Name of the file to searched for
     * @return true if the file is present, false if not
     */
    static bool validateFile(const std::string filename) {
        struct stat buffer;
        if (stat(filename.c_str(), &buffer) < 0) {
            return false;
        }
        return true;
    }

    ///\brief Purges existing files out of user-defined directory matching wildcard suffix
    /**
     * This function searches through the user-defined directory and will 
     * delete all files matching the specific suffix.
     * 
     * @param directory User-defined purging directory
     * @param suffix User defined suffix. NOTE: The suffix does not contain "."
     */
    static void purgeExistingFiles(const std::string directory, const std::string suffix) {
        // this function is designed to purge the existing files of this type suffix
        DIR *dp;
        struct dirent *dirp;
        if ((dp = opendir(directory.c_str())) == NULL) {
            std::cerr << "Error: " << errno << " opening " << directory << std::endl;
        }

        while ((dirp = readdir(dp)) != NULL) {
            std::string filename = std::string(dirp->d_name);
            if (filename.find_last_of(".") != std::string::npos) {
                std::string ext = filename.substr(filename.find_last_of(".") + 1);
                if (ext.compare(suffix) == 0) {
                    // if we found all this, lets make a big path and delete it
                    std::string bigFile = directory + "/" + filename;
                    if (remove(bigFile.c_str()) != 0) {
                        std::cerr << "Error: deleting file " << filename << std::endl;
                    }
                }
            }
        }

    }

    ///\brief Function returns the number of files matching a specific suffix
    /**
     * This function returns the specific number of files matching wildcard
     * suffix in the user-defined directory.
     * 
     * @param directory User-defined search directory
     * @param suffix User-defined search suffix
     * @return int Number of return files
     */
    static int getNumberOfFiles(const std::string directory, const std::string suffix) {
        DIR *dp;
        struct dirent *dirp;
        if ((dp = opendir(directory.c_str())) == NULL) {
            std::cerr << "Error: " << errno << " opening " << directory << std::endl;
            return errno;
        }

        int numFiles = 0;
        while ((dirp = readdir(dp)) != NULL) {
            // this is where we need to test for the suffix
            std::string filename = std::string(dirp->d_name);
            if (filename.find_last_of(".") != std::string::npos) {
                std::string ext = filename.substr(filename.find_last_of(".") + 1);
                if (ext.compare(suffix) == 0) {
                    numFiles++;
                }
            }
        }
        return numFiles;
    }

} // namespace TEST

#endif
